On the first click, and if no meta keys are used, it determines which cell was clicked and sends it a startTrackingAt:inView: message. This makes it possible for the cells to track the mouse even when in NX_LISTMODE.
If the user control-clicks a cell, it allows them to drag the cell to a new location.
*/
{
NXPoint pt;
int row, col;
NXRect cellFrame;
id clickedCell;
// Allow cells to track mouseDown events
if ( !theEvent->flags ) {
pt = theEvent->location;
[self convertPoint:&pt fromView:nil];
[self getRow:&row andCol:&col forPoint:&pt];
clickedCell = [self cellAt:row :0];
[self selectCell:clickedCell];
[self getCellFrame:&cellFrame at:row :0];
if ( [clickedCell mouseDownAt:&pt frame:&cellFrame inView:self] ) {
[self drawCellInside:clickedCell];
return ( self );
}
}
// Check for control-click
if ( (theEvent->flags & NX_CONTROLMASK)
&& !(theEvent->flags & NX_SHIFTMASK) ) {
[self controlDragMouse:theEvent];
return ( self );
}
// Check for alternate-click
if ( (theEvent->flags & NX_ALTERNATEMASK) ) {
[self alternateDragMouse:theEvent];
return ( self );
}
// Just act like normal
return ( [super mouseDown:theEvent] );
}
- controlDragMouse:(NXEvent *)theEvent
/*
Called when the user Control-clicks on a cell. This allows the cells to be reordered by dragging them to a new position.
*/
{
NXPoint pt;
int row, col, newRow;
NXRect cellFrame, visibleRect, cellCacheBounds;
int eventMask;
float dy;
NXEvent *event = NULL, peek;
NXTrackingTimer *timer = NULL;
BOOL scrolled = NO;
id group;
// Prepare the cell and matrix cache windows
[self setupCacheWindows];
// Tell the window to receive mouse-dragged events
// we need to shuffle cells if the active cell's going to a new location
if ( newRow != row ) {
// No autodisplay while we move cells around
[self setAutodisplay:NO];
// Move the item to it's new location within the group
group = cellList;
[group setChanged:YES];
[group removeObject:activeCell];
[group insertObject:activeCell at:newRow];
// if the active cell is selected, note its new row
if ( [activeCell state] )
selectedRow = newRow;
// make sure the active cell's visible if we're autoscrolling
if ( mFlags.autoscroll ) {
[self scrollCellToVisible:newRow :0];
}
// size to cells after all this shuffling and turn autodisplay back on
[[self sizeToCells] setAutodisplay:YES];
}
// No longer dragging the cell
activeCell = nil;
// Now redraw ourself
[self display];
// set the event mask mask to normal
[window setEventMask:eventMask];
return ( self );
}
- alternateDragMouse:(NXEvent *)theEvent
/*
Sent when the user alternate-clicks on a cell. This allows the selected items to be dragged out of this window to another folder or another application.
*/
{
id clickedCell;
char *files = NULL, *buf;
NXPoint pt, offs = { 24,24 };
int row, col;
NXStream *stream;
int len, mlen;
int i, count, k;
NXImage *img;
id pboard;
// Determine which cell the click happened in
pt = theEvent->location;
[self convertPoint:&pt fromView:nil];
[self getRow:&row andCol:&col forPoint:&pt];
clickedCell = [self cellAt:row :0];
// Make sure this cell is selected, then redraw
[clickedCell setState:1];
[self drawCellInside:clickedCell];
// behave as a single click
if ( !(theEvent->flags & NX_SHIFTMASK ) ) [self sendAction];
// Get list of all selected items, and put them into
// tab-separated string
stream = NXOpenMemory ( NULL, 0, NX_WRITEONLY );
if ( !stream ) { // Couldn't open stream
NXBeep();
return ( self );
}
k = 0; // This is the first item in the list
for ( i=0, count=[cellList count]; i<count; i++ ) {
Returns the currently selected cell. If there isn't one selected, or there is more than one, returns nil. Updates selectionCount to hold the number of cells selected
*/
{
// Returns selectedCell only if a single cell is selected
if ( selectionCount == 1 ) return ( selectedCell );
else return ( nil );
}
- determineSelectionCount
{
register int i, count;
// Reset selectionCount
selectionCount = 0;
// Get the number of selected cells
for ( i=0, count=[self cellCount]; i<count; i++ )
if ( [[self cellAt:i :0] state] ) selectionCount++;
return ( self );
}
- selection
/*
Acts like selectedCell, but if multiple items are selected, it returns the selection list ( see -selectionList)
*/
{
static id list = nil;
if ( list ) {
[list free];
list = nil;
}
if ( selectionCount == 1 ) return ( selectedCell );